#!/bin/bash
set -eEuo pipefail
# the canonical path of this script
SELF_PATH=$(realpath -- "$0")
readonly SELF_PATH SELF_DIR=${SELF_PATH%/*}

readonly BASH_BUDDY_ROOT="$SELF_DIR/bash-buddy"
# shellcheck disable=SC1091
source "$BASH_BUDDY_ROOT/lib/trap_error_info.sh"
# shellcheck disable=SC1091
source "$BASH_BUDDY_ROOT/lib/common_utils.sh"
# shellcheck disable=SC1091
source "$BASH_BUDDY_ROOT/lib/java_utils.sh"
# shellcheck disable=SC1091
source "$BASH_BUDDY_ROOT/lib/maven_utils.sh"

################################################################################
# ci build logic
################################################################################

readonly default_build_jdk_version=21
readonly JDK_VERSIONS=(
  8
  11
  17
  "$default_build_jdk_version"
  23
)

# here use `install` and `-D performRelease` intended
#   to check release operations.
#
# De-activate a maven profile from command line
#   https://stackoverflow.com/questions/25201430
#
# shellcheck disable=SC2034
readonly MVU_MVN_OPTS=(
  "${MVU_DEFAULT_MVN_OPTS[@]}"
  -DperformRelease
  ${CI_MORE_MVN_OPTS:+${CI_MORE_MVN_OPTS}}
  -P!gen-sign -P!enforce-project-version-when-release
  dependency:tree
)

# cd to the project root directory
readonly PROJECT_ROOT=${SELF_DIR%/*}
cd "$PROJECT_ROOT"

########################################
# build and test by default version jdk
########################################

jvu::switch_to_jdk "$default_build_jdk_version"

cu::log_then_run scripts/gen_CffuApiCompatibilityTest.sh

cu::head_line_echo "build and test with Java $default_build_jdk_version: $JAVA_HOME"
mvu::mvn_cmd clean install

########################################
# test by multiple version jdks
########################################

# shellcheck disable=SC2034
readonly MVN_OPTS_FOR_JAVA8=(
  -Dkotlin.version=1.6.0 -Dguava.version=29.0-jre
  -P!default-logging-dependencies -P!default-arch-unit-test
)
# shellcheck disable=SC2034
readonly MVN_OPTS_FOR_JAVA11=(
  -Dkotlin.version=1.7.0
  -DswitchToLog4j2LoggingDependencies -Pswitch-slf4j-to-v1
)
# shellcheck disable=SC2034
readonly MVN_OPTS_FOR_JAVA17=(
  -Dkotlin.version=1.8.0
  -DswitchToLog4j2LoggingDependencies -Dcffu.uncaught.exception.report=full
)
# shellcheck disable=SC2034
readonly MVN_OPTS_FOR_JAVA23=(
  -Dkotlin.version=1.9.0
  -Dcffu.uncaught.exception.report=none
)

SUREFIRE_TEST_GOAL=(surefire:test)
# about CI env var
#   https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables
[ "${CI:-}" = true ] && SUREFIRE_TEST_GOAL=(jacoco:prepare-agent "${SUREFIRE_TEST_GOAL[@]}" jacoco:report)
readonly SUREFIRE_TEST_GOAL

for jdk_version in "${JDK_VERSIONS[@]}"; do
  # skip default jdk, already tested above
  [ "$jdk_version" = "$default_build_jdk_version" ] && continue

  jvu::switch_to_jdk "$jdk_version"

  # skip kotlin module test for low java version(19-)
  # need recompile and test later(more info see the comments)
  pl=()
  if ((jdk_version < default_build_jdk_version && jdk_version < 19)); then
    pl=(-pl 'cffu-core,cffu-ttl-executor-wrapper')
  fi

  mvn_opts_for_java_version_var_name="MVN_OPTS_FOR_JAVA${jdk_version}[@]"

  # just test without build
  cu::head_line_echo "test with Java $jdk_version: $JAVA_HOME"
  mvu::mvn_cmd ${!mvn_opts_for_java_version_var_name:+"${!mvn_opts_for_java_version_var_name}"} \
    ${pl[@]:+"${pl[@]}"} "${SUREFIRE_TEST_GOAL[@]}"
done

# test the kotlin extension methods works
#
# CAUTION: MUST recompile the client sources(test codes) by Java 8
#   Extensions are resolved statically.
#   If a class has a member function, and an extension function is defined
#     which has the same receiver type, the same name, and is applicable to given arguments,
#   the member always wins
#   https://kotlinlang.org/docs/extensions.html#extensions-are-resolved-statically
#
# RECOMPILE cffu-kotlin and run test

cd cffu-kotlin
rm -rf target/*test*
jvu::switch_to_jdk 8

cu::head_line_echo "recompile and test cffu-kotlin with Java 8: $JAVA_HOME"
mvu::mvn_cmd -Dmaven.main.skip -Denforcer.skip -P!gen-git-properties \
  test-compile "${SUREFIRE_TEST_GOAL[@]}"

for jdk_version in "${JDK_VERSIONS[@]}"; do
  # skip jdk 8, already tested above
  ((jdk_version == 8)) && continue

  jvu::switch_to_jdk "$jdk_version"

  mvn_opts_for_java_version_var_name="MVN_OPTS_FOR_JAVA${jdk_version}[@]"

  # just test without build
  cu::head_line_echo "test cffu-kotlin with Java $jdk_version: $JAVA_HOME"
  mvu::mvn_cmd -Dmaven.main.skip -Denforcer.skip \
    ${!mvn_opts_for_java_version_var_name:+"${!mvn_opts_for_java_version_var_name}"} \
    "${SUREFIRE_TEST_GOAL[@]}"
done
